#include <string.h>
#include <errno.h>
#include <sys/un.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>

#include <linux/input.h>

#include "result.h"
#include "epoll.h"
#include <cutils/sockets.h>


#define LOG_TAG "mysrv_test"
//#include <android/log.h>
#include <log/log.h>

using namespace android::init;

#define SOCKET_NAME_TEST  "mysock"
static int s_fdListen = -1;
static int input_fd = -1;

void handle_socket_fd()
{
	int ret = -1;
	int new_fd = -1; 
	char cmd[256];

	if(s_fdListen > 0){
		new_fd = accept(s_fdListen, nullptr, nullptr);
		if (new_fd < 0) {
	        	return;
	    	}
		bzero(cmd, sizeof(cmd));
		ret = recv(new_fd, cmd,  256, 0);	
		if(ret < 0){
	        	ALOGE("recv socket error : %s ", strerror(errno));
	        	return;
		}
		cmd[ret] = '\0';
	}
	
	ALOGE("recv client cmd: %s \n",cmd);
	close(new_fd);
	
}

void setup_socket(Epoll* epoll)
{
	//s_fdListen = android_get_control_socket(SOCKET_NAME_TEST);
	s_fdListen = socket(AF_LOCAL, SOCK_STREAM, 0);
		if (s_fdListen < 0) {
		ALOGE("get control socket error, name :  %s", SOCKET_NAME_TEST); 
		exit(-1);
	}
	std::string path = "/dev/socket/mysocket" ;
	unlink(path.c_str());	
	
	struct sockaddr_un  addr;
	addr.sun_family = AF_LOCAL;
  	strlcpy(addr.sun_path, path.c_str(), sizeof(addr.sun_path));
	bind(s_fdListen, (const struct sockaddr *)&addr, sizeof(addr));

	listen(s_fdListen, 4);

	if (auto result = epoll->RegisterHandler(s_fdListen, handle_socket_fd); !result) {
		ALOGE("epoll RegisterHandler error: %s", result.error().error_string.c_str());
		exit(1);
    	}
}

void handle_inputdev_fd()
{
	struct input_event event;
	int ret = -1;
	
	if(input_fd > 0){
		bzero(&event,sizeof(event));
		ret = read(input_fd, &event, sizeof(event));
		if(ret < 0){
			ALOGE("read inputdev error :  %s",  strerror(errno));
			return ;
		}
		ALOGI("type=%d, code=%d, value=%d", event.type, event.code, event.value);
	}
}

void setup_input_dev(Epoll* epoll)
{	
	/*
		:/ # sendevent /dev/input/event0 1 102 1
		:/ # sendevent /dev/input/event0 1 102 0
		:/ # sendevent /dev/input/event0 0 0 0
	*/
	std::string dev_name = "/dev/input/event0";
	input_fd = open(dev_name.c_str(), O_RDWR);
	if (input_fd < 0) {
		ALOGE("open %s error :  %s", dev_name.c_str(), strerror(errno));
		return ;
   	}

	if (auto result = epoll->RegisterHandler(input_fd, handle_inputdev_fd); !result) {
		ALOGE("epoll RegisterHandler error: %s", result.error().error_string.c_str());
		close(input_fd);
		return ;
   	}
}



int main(int argc, char *argv[])
{
	//初始化epoll
    	Epoll epoll;
	if (auto result = epoll.Open(); !result) {
		ALOGE("epoll Open error: %s", result.error().error_string.c_str());
		exit(1);
    	}	

	setup_socket(&epoll);
	setup_input_dev(&epoll);
	while(true){
		auto epoll_timeout = std::optional<std::chrono::milliseconds>{};
		if (auto result = epoll.Wait(epoll_timeout); !result) {
			ALOGE("epoll Wait error: %s", result.error().error_string.c_str());
		}
	}

	return 0;
}



